package cn.vshare.controller;

import cn.vshare.entity.Role;
import cn.vshare.entity.User;
import cn.vshare.service.RoleService;
import cn.vshare.service.UserService;
import cn.vshare.util.DateUtil;
import cn.vshare.util.IpUtil;
import cn.vshare.util.JSON2Console;
import com.alibaba.fastjson.JSON;
import org.apache.log4j.Logger;
import org.apache.log4j.MDC;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
public class UserController {
    @Resource(name = "userServiceImpl")
    private UserService userService;
    private Logger log = Logger.getLogger(MessageAction.class); //引入日志类
    @Autowired
    private RoleService roleService;


    /**
     * 访问后台管理员登录界面
     *
     * @return
     */
    @RequestMapping("/forwardAdminLogin")
    public ModelAndView forwardAdminLogin() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("h-ui/adminLogin");
        return modelAndView;
    }

    /**
     * 访问前台会员登录界面
     *
     * @return
     */
    @RequestMapping("/forwardUserLogin")
    public ModelAndView forwardUserLogin() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("login");
        return modelAndView;
    }


    @RequestMapping("/getAllFriend")
    public List<User> getAllFriend(HttpSession session) {
        User user = (User) session.getAttribute("USER");
        List<User> list = userService.getAllFriend(user);
        return list;
    }


    @RequestMapping(value = "/toIndex")
    public ModelAndView toIndex() {
        //return new ModelAndView("forward:index.html");
        System.out.println("=========具备该权限,正常跳转====");
        return new ModelAndView("index");
        //return new ModelAndView("closeLayer");
    }

    @RequestMapping(value = "/need2Login")
    public String need2Login() {
        System.out.println("=========不具备该权限,需要进行账户登录====");
        return "need2Login";
    }

    @RequestMapping(value = "/need2GetPermission")
    public String need2GetPermission() {
        System.out.println("=========不具备该权限,需要进行授权====");
        return "need2GetPermission";
    }


    @RequestMapping(value = "/toFail")
    public ModelAndView toFail() {
        //return new ModelAndView("forward:index.html");
        //return new ModelAndView("toFail");
        return new ModelAndView("404toFail");
        //return new ModelAndView("closeLayer");
    }

    /**
     * 20181008wyl
     * 1-登录用户的信息查询(User-Role-PermissionSecond),并将其存入到Session域中
     */
    @RequestMapping("login")
    public ModelAndView login(User user, HttpSession session,
                              @RequestParam(name = "code2Validate", required = true) String code2Validate) {

        /*20181016wyl*/
        //登录过程其实只是处理异常的相关信息，具体的登录验证交给shiro来处理

        //得到登录时的验证码
        String codeValidate2Session = (String) session.getAttribute("codeValidate");
        Map<String, Object> map = new HashMap<>();

        //System.out.println("codeValidate======"+codeValidate);

        if (!code2Validate.equalsIgnoreCase(codeValidate2Session)) {
            //验证码填写错误
            return new ModelAndView("redirect:login.html");
        } else {
            //验证码填写正确
            //shiro框架的启用,使用过滤器链
            //启用shiro的身份认证及授权管理,
            Subject subject = SecurityUtils.getSubject();
            UsernamePasswordToken usernamePasswordToken =
                    new UsernamePasswordToken(user.getNickName(), user.getPassword());

            ModelAndView modelAndView = new ModelAndView();
            String msg = "";
            try {
                subject.login(usernamePasswordToken);//启用shiro的身份认证及授权管理,
                if (subject.isAuthenticated()) {
                    System.out.println("登录成功");
                    return new ModelAndView("redirect:toIndex.do");
                } else {
                    System.out.println("登录失败");
                    return new ModelAndView("redirect:login.html");
                }
            } catch (IncorrectCredentialsException e) {
                msg = "1登录账号/密码错误,Password for account " + usernamePasswordToken.getPrincipal() + " was Incorrect";
                modelAndView.addObject("message", msg);
                System.out.println(msg);
            } catch (ExcessiveAttemptsException e) {
                msg = "2登录失败次数过多";
                modelAndView.addObject("message", msg);
                System.out.println(msg);
            } catch (LockedAccountException e) {
                msg = "3账号被锁定, The account for userName  " + usernamePasswordToken.getPrincipal() + " was locked";
                modelAndView.addObject("message", msg);
                System.out.println(msg);
            } catch (DisabledAccountException e) {
                msg = "4账号被禁用, The account for userName  " + usernamePasswordToken.getPrincipal() + " was disabled";
                modelAndView.addObject("message", msg);
                System.out.println(msg);
            } catch (ExpiredCredentialsException e) {
                msg = "5账号的密码已过期,超时, The account for userName  " + usernamePasswordToken.getPrincipal() + " was expired";
                modelAndView.addObject("message", msg);
                System.out.println(msg);
            } catch (UnknownAccountException e) {
                msg = "6账号不存在,There is no user with username of " + usernamePasswordToken.getPrincipal();
                modelAndView.addObject("message", msg);
                System.out.println(msg);
            } catch (UnauthorizedException e) {
                msg = "7您没有得到相应的授权, " + e.getMessage();
                modelAndView.addObject("message", msg);
                System.out.println(msg);
            }

            System.out.println("出现异常,返回登录页面");
            return new ModelAndView("redirect:login.html");
        }//else结束
    }

    /**
     * 20181008wyl
     * 1-登录用户的信息查询(User-Role-PermissionSecond),并将其存入到Session域中
     */
    @RequestMapping(value = "/login2Layer.do")
    @ResponseBody
    public ModelAndView login2Layer(User user, HttpSession session,
                                    HttpServletResponse response,
                                    @RequestParam(name = "code2Validate", required = true) String code2Validate) {

        ModelAndView modelAndView = new ModelAndView();

        //得到登录时的验证码
        String codeValidate2Session = (String) session.getAttribute("codeValidate");
        Map<String, Object> map = new HashMap<>();

        //System.out.println("codeValidate======"+codeValidate);

        if (!code2Validate.equalsIgnoreCase(codeValidate2Session)) {
            //验证码填写错误
            modelAndView.setViewName("login2Layer");
            return modelAndView;
        } else {
            //验证码填写正确
            //shiro框架的启用,使用过滤器链
            //启用shiro的身份认证及授权管理,
            Subject subject = SecurityUtils.getSubject();
            UsernamePasswordToken usernamePasswordToken =
                    new UsernamePasswordToken(user.getNickName(), user.getPassword());


            String msg = "";
            try {
                subject.login(usernamePasswordToken);//启用shiro的身份认证及授权管理,
                if (subject.isAuthenticated()) {
                    System.out.println("登录成功");
                    modelAndView.addObject("msg", "success");
                    modelAndView.setViewName("login2Message");
                    return modelAndView;

                } else {
                    System.out.println("登录失败");
                    return new ModelAndView("login2Message");
                }
            } catch (IncorrectCredentialsException e) {
                msg = "1登录账号/密码错误,Password for account " + usernamePasswordToken.getPrincipal() + " was Incorrect";
                modelAndView.addObject("message", msg);
                System.out.println(msg);
            } catch (ExcessiveAttemptsException e) {
                msg = "2登录失败次数过多";
                modelAndView.addObject("message", msg);
                System.out.println(msg);
            } catch (LockedAccountException e) {
                msg = "3账号被锁定, The account for userName  " + usernamePasswordToken.getPrincipal() + " was locked";
                modelAndView.addObject("message", msg);
                System.out.println(msg);
            } catch (DisabledAccountException e) {
                msg = "4账号被禁用, The account for userName  " + usernamePasswordToken.getPrincipal() + " was disabled";
                modelAndView.addObject("message", msg);
                System.out.println(msg);
            } catch (ExpiredCredentialsException e) {
                msg = "5账号的密码已过期,超时, The account for userName  " + usernamePasswordToken.getPrincipal() + " was expired";
                modelAndView.addObject("message", msg);
                System.out.println(msg);
            } catch (UnknownAccountException e) {
                msg = "6账号不存在,There is no user with username of " + usernamePasswordToken.getPrincipal();
                modelAndView.addObject("message", msg);
                System.out.println(msg);
            } catch (UnauthorizedException e) {
                msg = "7您没有得到相应的授权, " + e.getMessage();
                modelAndView.addObject("message", msg);
                System.out.println(msg);
            }


        }//else结束

        System.out.println("出现异常,返回登录页面");
        return new ModelAndView("login2Message");
    }


    /**
     * 管理员登录
     *
     * @param user
     * @return
     */
    @RequestMapping("/adminLogin")
    public ModelAndView adminLogin(User user, HttpSession session,
                                   @RequestParam(name = "code2Validate", required = true) String code2Validate) {
        //得到登录时的验证码
        String codeValidate2Session = (String) session.getAttribute("codeValidate");
        //System.out.println("codeValidate======"+codeValidate);

        ModelAndView mv = new ModelAndView();
        if (!code2Validate.equalsIgnoreCase(codeValidate2Session)) {
            //验证码填写错误
            return new ModelAndView("redirect:/forwardAdminLogin.do");
        } else {
            //验证码填写正确
            //shiro框架的启用,使用过滤器链
            //启用shiro的身份认证及授权管理,

            Subject subject = SecurityUtils.getSubject();
            UsernamePasswordToken token = new UsernamePasswordToken(user.getNickName(), user.getPassword());
            try {
                subject.login(token);
               // User newUser = (User) subject.getSession().getAttribute("USER");//shiro中使用session存储
                //System.out.println(JSON.toJSONString(newUser));
                //mv.setViewName("h-ui/admin");//20181016wyl,转个弯,加个中介挑转:299
                return new ModelAndView("redirect:/toAdminFtl.do");
            } catch (Exception e) {
                e.printStackTrace();
                mv.addObject("result", "用户名会密码不正确!");
                mv.setViewName("h-ui/404");
            }
        }
        return mv;
    }

    @RequestMapping(value = "/toAdminFtl")
    public ModelAndView toAdminFtl(){
        return new ModelAndView("h-ui/admin");
    }

    @RequestMapping("/getUserInfo")
    public ModelAndView getUserInfo(User user, HttpServletRequest request) {
        System.out.println("sssssssss" + JSON.toJSONString(user));
        ModelAndView mv = new ModelAndView();
        User newUser = userService.queryUserById(user);
        if (newUser != null) {
            mv.addObject(newUser);
            mv.setViewName("h-ui/member-show");
        } else {
            mv.setViewName("redirect:/h-ui/404.html");
        }
        //记录操作日志
        MDC.put("id", UUID.randomUUID().toString()); //主键
        MDC.put("uid", "2bb03abc-03d0-4115-a2c9-eef51556d6a5"); //记录操作的用户id
        MDC.put("ip", IpUtil.getIp(request));  //记录访问的ip地址
        log.info("获取用户:" + newUser.getNickName() + "的详细信息");
        return mv;
    }

    @RequestMapping("/delUser")
    public String delUser(String id, HttpServletRequest request) {
        User user = new User();
        user.setId(id);
        User newUser = userService.queryUserById(user); //获取用户对象
        userService.delUserById(id);

        //记录操作日志
        MDC.put("id", UUID.randomUUID().toString()); //主键
        MDC.put("uid", "2bb03abc-03d0-4115-a2c9-eef51556d6a5"); //记录操作的用户id
        MDC.put("ip", IpUtil.getIp(request));  //记录访问的ip地址
        log.info("删除用户:" + newUser.getNickName());
        return "success";
    }

    @RequestMapping("/recoverDelUser")
    public String recoverDelUser(String id, HttpServletRequest request) {
        User user = new User();
        user.setId(id);
        User newUser = userService.queryUserById(user); //获取用户对象
        userService.recoverDelUser(id);  //执行用户信息恢复方法

        //记录操作日志
        MDC.put("id", UUID.randomUUID().toString()); //主键
        MDC.put("uid", "2bb03abc-03d0-4115-a2c9-eef51556d6a5"); //记录操作的用户id
        MDC.put("ip", IpUtil.getIp(request));  //记录访问的ip地址
        log.info("恢复被删除的用户:" + newUser.getNickName());
        return "success";
    }


    //http://localhost:8080/register.html
    @RequestMapping(value = "register")
    public ModelAndView register(User user, HttpServletRequest request,
                                 @RequestParam(name = "upload2file", required = false) MultipartFile file) {
        //s1:主键UUID
        String id2UUID = UUID.randomUUID().toString();
        user.setId(id2UUID);
        //s2:普通用户的UUID
        user.setRole(new Role("dbe554a5-2085-40c3-aebe-5b69a7c5feae"));
        //s3:密码加密,暂不使用,长度为32位的字符串
       /* user.setPassword(PasswordUtil.md5Password(user.getPassword()));
        System.out.println(user.getPassword());*/
        //s4:头像图片的保存
        if (!file.isEmpty()) {
            //获取当前时间
            DateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
            String currDate = format.format(new Date());
            //获取随机数
            int random = new Random().nextInt(10000);
            //获取原始的文件名称
            String originalName = file.getOriginalFilename();
            //获取文件的后缀名
            String extension = originalName.substring(originalName.lastIndexOf("."));
            //生成新的文件名,防止出现相同的文件名
            String newFileName = currDate + "-" + random + "-" + originalName;
            //文件保存路径,以web.xml的根路径为依据
            String fliePath = newFileName;
            try {
                file.transferTo(new File(fliePath));
                user.setPic(newFileName);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        //注册时间
        user.setRegisterDate(DateUtil.getCurrDate());

        int insertRecord = userService.register(user);

        ModelAndView modelAndView = new ModelAndView();
        if (insertRecord == 1) {
            System.out.println("注册成功");
            modelAndView.setViewName("redirect:login.html");
        } else {
            System.out.println("注册失败");
            modelAndView.setViewName("redirect:register.html");
        }
        return modelAndView;
    }


    @RequestMapping("/countUserByRole")
    public Map<String, Object> countUserByRole() {
        Map<String, Object> map = new HashMap<String, Object>();
        List<Role> roleList = roleService.queryAllRole(); //获取所有角色
        for (Role role : roleList) {
            int count = userService.countUserByRole(role); //获取每个角色的人数
            map.put(role.getName(), count); //封装查询结果
        }
        return map;
    }


    @RequestMapping("/forwardMemberAdd")
    public ModelAndView forwardMemberAdd() {
        ModelAndView mv = new ModelAndView();
        mv.setViewName("h-ui/member-add");
        return mv;
    }

    @RequestMapping("/forwardMemberLevel")
    public ModelAndView forwardMemberLevel() {
        ModelAndView mv = new ModelAndView();
        mv.setViewName("h-ui/member-level");
        return mv;
    }

    @RequestMapping("forwardUserArea")
    public ModelAndView forwardUserArea() {
        return new ModelAndView("user_area");
    }


    @RequestMapping("/getUserFromSession")
    public User getUserFromSession(HttpSession session) {
        User user = (User) session.getAttribute("USER");
        if (user == null) {
            user = new User();
        }
        return user;
    }

    /*前台*/
    @RequestMapping("/logoff")
    public ModelAndView logoff(HttpSession session) {
        /*解决关于shiro的Error:10181008wyl*/
        //使用shiro的退出登录
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        //session.invalidate();
        return new ModelAndView("redirect:index.html");
    }

    @RequestMapping("/changeAccount")
    public ModelAndView changeAccount(HttpSession session) {
        /*解决关于shiro的Error:10181008wyl*/
        //使用shiro的退出登录
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        //session.invalidate();
        return new ModelAndView("redirect:login.html");
    }


    /*20181015后台*/
    @RequestMapping("/logoff2Admin")
    public ModelAndView logoff2Admin(HttpSession session) {
        /*解决关于shiro的Error:10181008wyl*/
        //使用shiro的退出登录
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        //session.invalidate();
        return new ModelAndView("redirect:/forwardAdminLogin.do");
    }

    @RequestMapping("/changeAccount2Admin")
    public ModelAndView changeAccount2Admin(HttpSession session) {
        /*解决关于shiro的Error:10181008wyl*/
        //使用shiro的退出登录
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        //session.invalidate();
        return new ModelAndView("redirect:/forwardAdminLogin.do");
    }

    @RequestMapping("getUserById")
    public User getUserById(User user) {
        return userService.queryUserById(user);
    }

    /**
     * 添加好友 封装了 myId friendId
     *
     * @param map
     */
    @RequestMapping("addFriend")
    public void addFriend(@RequestParam Map map) {
        map.put("date", DateUtil.getCurrDate());
        map.put("isBlack", 1);
        userService.addFriend(map);
    }

    @RequestMapping("isExistFriend")
    public int isExistFriend(String myId, String friendId) {
        return userService.isExistFriend(myId, friendId);
    }

    @RequestMapping("removeFriend")
    public void removeFriend(String myId, String friendId) {
        userService.removeFriend(myId, friendId);
    }


    @RequestMapping(value = "getUserId")
    public ModelAndView getUserId(User user1) {
        JSON2Console.output2Cnsole(user1);
        User userInfo = userService.queryUserById(user1);
        JSON2Console.output2Cnsole(userInfo);

        //设置头像图片的完整的保存路径
        //文件保存路径,以web.xml的根路径为依据
        /*20181009暂不设置,前台显示有误,古使用原始值*/
        /*String newFilePath="D:\\2080912V_Sharing_Fun_Business\\20180912V_Sharing_Fun_Code\\V_Share\\src\\main\\webapp\\20181009file\\video\\aaaaatemp\\";
        newFilePath=newFilePath+userInfo.getPic();
        userInfo.setPic(newFilePath);*/

        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("edit2UserInfo", userInfo);//测试使用的


        //personal.jsp,由spring-mvc.xml:75的自定义InternalResourceViewResolver解析器解析成personal.jsp
        modelAndView.setViewName("personal");
        return modelAndView;
    }

    @RequestMapping(value = "updateUserInfo")
    public ModelAndView updateUserInfo(User user, String sex,
                                       @RequestParam(name = "upload2file", required = false) MultipartFile file) {

        //s1:查询更新后的数据
        //System.out.println("================"+sex);//该表单的接收是 <textarea name="sex">:190
        user.setSex(sex);
        JSON2Console.output2Cnsole(user);
        //JSON2Console.output2Cnsole(file);

        /*20181009wyl*/
        /*
         * BUG:在更新用户信息时,更新头像使用的是异步技术,所以和用户的其他信息不一起更新,
         * 即在点击头像,并且头像预览后,已经完成了头像的数据库更新操作
         *该BUG不影响正常使用,但可能有以后存在未知异常,几率较小
         * */
        //s2:头像图片的保存
        if (!file.isEmpty()) {
            //获取当前时间
            DateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
            String currDate = format.format(new Date());
            //获取随机数
            int random = new Random().nextInt(10000);
            //获取原始的文件名称
            String originalName = file.getOriginalFilename();
            //获取文件的后缀名
            String extension = originalName.substring(originalName.lastIndexOf("."));
            //生成新的文件名,防止出现相同的文件名
            String newFileName = currDate + "-" + random + "-" + originalName;
            //文件保存路径,以web.xml的根路径为依据
            String fliePath = newFileName;
            try {
                file.transferTo(new File(fliePath));
                user.setPic(newFileName);//更新头像图片信息
                //测试
                //System.out.println(newFileName);
                //JSON2Console.output2Cnsole(user);

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        int insertRecord = userService.updateUser(user);

        ModelAndView modelAndView = new ModelAndView();
        if (insertRecord == 1) {
            System.out.println("更新成功");
            modelAndView.setViewName("forward:getUserId.do");
        } else {
            System.out.println("跟新失败");
            modelAndView.setViewName("forward:getUserId.do");
        }
        return modelAndView;
    }

}
